<script setup lang="ts">
import { useQuickStartStore } from "@/store/modules/quick-start"
import { computed } from "vue"
import { CreateOrUpdateTaskData } from "@/api/task/types/task"
import { ElMessage, FormInstance, FormRules } from "element-plus"
import { cloneDeep } from "lodash-es"
import { onMounted, ref } from "vue"
import { TASK_MODE, taskModeOptions, evalIndexOptions } from "@/constants/other-keys"
import { getSceneListApi } from "@/api/resources/scene"
import { SceneTableData } from "@/api/resources/scene/types/scene"
import { createTaskDataApi } from "@/api/task"
import { GCTableData } from "@/api/resources/game-config/types/game-config"
import { getGCListApi } from "@/api/resources/game-config"

interface Props {
  id: string | undefined | null
  gcId: string | undefined | null // 博弈配置id
  trainTaskId: string | undefined | null
  type: TASK_MODE
}
const props = defineProps<Props>()
const emit = defineEmits(["update:trainTaskId", "toNext"])
const gameId = ref<string | undefined>(props.id as string)
const associateId = ref<string | undefined>(props.gcId as string)
const store = useQuickStartStore()
const modeType = computed(() => {
  return store.modeType
})
const DEFAULT_FORM_DATA: CreateOrUpdateTaskData = {
  task_id: undefined,
  /** 任务名称 */
  task_name: "",
  /** 任务描述 */
  task_describe: "",
  /** 场景id */
  game_id: gameId.value,
  /** 任务类型 */
  task_type: modeType.value,
  /** 博弈配置 */
  associate_id: associateId.value,
  /** 任务算法标签 */
  task_tag: "",
  /** 任务状态 */
  task_status: 0,
  /** 评估指标 */
  task_eval_tag: [],
  /** task_param */
  task_param: {
    task_config: {
      mode: props.type,
      resources: {
        distributed_enable: false,
        cpu_num: 1,
        gpu_num: 1,
        worker_num: 1
      }
    },
    episode_config: {
      max_episode: 1
    },
    test_config: {
      test_interval: 1,
      test_num: 1
    },
    save_config: {
      training_sample_data: {
        save_enable: true,
        save_path: undefined
      },
      decision_model: {
        save_enable: true,
        save_path: undefined
      },
      win_rate: {
        save_enable: true,
        save_path: undefined
      }
    }
  }
}
const loading = ref<boolean>(false)
const formRef = ref<FormInstance | null>(null)
const formData = ref<CreateOrUpdateTaskData>(cloneDeep(DEFAULT_FORM_DATA))
const formRules: FormRules<CreateOrUpdateTaskData> = {
  task_name: [{ required: true, trigger: "blur", message: "请输入任务名称" }],
  game_id: [{ required: true, trigger: "change", message: "请选择任务场景" }],
  "task_param.task_config.mode": [{ required: true, trigger: "change", message: "请选择任务模式" }]
}
const taskSceneOptions = ref<SceneTableData[]>([])
const gcOptions = ref<GCTableData[]>([])
const taskId = ref<string>("")

const handleCreateOrUpdate = (isToNext: boolean) => {
  formRef.value?.validate((valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)
    loading.value = true
    createTaskDataApi({
      task_id: formData.value.task_id,
      task_name: formData.value.task_name,
      task_describe: formData.value.task_describe,
      game_id: gameId.value,
      task_type: modeType.value,
      task_status: formData.value.task_status,
      associate_id: formData.value.associate_id,
      task_tag: formData.value.task_tag,
      task_eval_tag: formData.value.task_eval_tag,
      task_param: formData.value.task_param
    })
      .then(({ data }) => {
        taskId.value = data.task_id
        emit("update:trainTaskId", taskId.value)
        if (isToNext) emit("toNext")
        ElMessage.success("操作成功")
        loading.value = false
      })
      .finally(() => {
        loading.value = false
      })
  })
}
const getSceneOptions = () => {
  getSceneListApi(modeType.value)
    .then(({ data }) => {
      taskSceneOptions.value = data
    })
    .catch(() => {
      taskSceneOptions.value = []
    })
}
const getGcOptions = () => {
  getGCListApi()
    .then(({ data }) => {
      gcOptions.value = data
    })
    .catch(() => {
      gcOptions.value = []
    })
}

const getTaskId = () => {
  return taskId.value
}

onMounted(() => {
  getSceneOptions()
  getGcOptions()
})

defineExpose({ getTaskId })
</script>

<template>
  <el-form ref="formRef" class="taskedit-form" :model="formData" :rules="formRules" label-width="auto" size="large">
    <div v-if="type == 'Train'" class="tip custom-block">
      <p class="custom-block-title">TIP：对训练任务进行配置，包括<strong>训练轮数，硬件需求等</strong>。</p>
    </div>
    <div v-else class="tip custom-block">
      <p class="custom-block-title">TIP：选择对智能体的评估维度，包括感知、认知、决策、行动等方面。</p>
    </div>
    <div class="title">
      <svg-icon name="icon-task" />
      <h3>任务信息</h3>
    </div>
    <el-row>
      <el-form-item label="任务名称" prop="task_name">
        <el-input v-model="formData.task_name" placeholder="请输入" />
      </el-form-item>
      <el-form-item label="任务场景" prop="game_id">
        <el-select v-model="formData.game_id" clearable placeholder="请选择" style="width: 240px">
          <el-option
            v-for="item in taskSceneOptions"
            :key="item.game_id"
            :label="item.game_name"
            :value="item.game_id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="任务模式" prop="task_param.task_config.mode">
        <el-select
          v-model="formData.task_param.task_config.mode"
          clearable
          disabled
          placeholder="请选择"
          style="width: 240px"
        >
          <el-option v-for="item in taskModeOptions" :key="item.value" :label="item.name" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="博弈配置" prop="associate_id">
        <el-select v-model="formData.associate_id" clearable disabled style="width: 240px">
          <el-option
            v-for="item in gcOptions"
            :key="item.by_config_id"
            :label="item.by_config_name"
            :value="item.by_config_id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="算法标签" prop="task_tag">
        <el-input v-model="formData.task_tag" placeholder="请输入" />
      </el-form-item>
    </el-row>
    <el-form-item v-if="props.type == 'Inference'" label="评估指标" prop="task_eval_tag">
      <el-checkbox-group v-model="formData.task_eval_tag as (string | number)[]">
        <el-checkbox v-for="item in evalIndexOptions" :key="item.value" :label="item.name" :value="item.value">
          {{ item.name }}
        </el-checkbox>
      </el-checkbox-group>
    </el-form-item>
    <el-form-item label="任务描述" prop="task_describe">
      <el-input v-model="formData.task_describe" :rows="3" type="textarea" placeholder="请输入" />
    </el-form-item>
    <el-divider />
    <div class="title">
      <svg-icon name="icon-resource" />
      <h3>资源配置</h3>
    </div>
    <el-form-item label="算法分布能力" prop="task_param.task_config.resources.distributed_enable">
      <el-switch v-model="formData.task_param.task_config.resources.distributed_enable" />
    </el-form-item>
    <el-row>
      <el-form-item label="CPU数量" prop="task_param.task_config.resources.cpu_num">
        <el-input
          :disabled="!formData.task_param.task_config.resources.distributed_enable"
          v-model="formData.task_param.task_config.resources.cpu_num"
          placeholder="请输入"
        />
      </el-form-item>
      <el-form-item label="GPU数量" prop="task_param.task_config.resources.gpu_num">
        <el-input
          :disabled="!formData.task_param.task_config.resources.distributed_enable"
          v-model="formData.task_param.task_config.resources.gpu_num"
          placeholder="请输入"
        />
      </el-form-item>
    </el-row>
    <el-form-item label="Worker数量" prop="task_param.task_config.resources.worker_num">
      <el-input
        :disabled="!formData.task_param.task_config.resources.distributed_enable"
        v-model="formData.task_param.task_config.resources.worker_num"
        placeholder="请输入"
        style="width: 200px"
        :controls="false"
      />
    </el-form-item>
    <el-divider />
    <div class="title">
      <svg-icon name="icon-train" />
      <h3>训练配置</h3>
    </div>
    <el-form-item label="最大轮数" prop="task_param.episode_config.max_episode">
      <el-input
        v-model="formData.task_param.episode_config.max_episode"
        placeholder="请输入"
        style="width: 200px"
        :controls="false"
      />
    </el-form-item>
    <el-divider />
    <div class="title">
      <svg-icon name="icon-test" />
      <h3>测试配置</h3>
    </div>
    <el-row>
      <el-form-item label="测试间隔轮数" prop="task_param.test_config.test_interval">
        <el-input
          :disabled="formData.task_param.task_config.mode == 'Inference'"
          v-model="formData.task_param.test_config.test_interval"
          placeholder="请输入"
        />
      </el-form-item>
      <el-form-item label="测试轮数" prop="task_param.test_config.test_num">
        <el-input
          :disabled="formData.task_param.task_config.mode == 'Inference'"
          v-model="formData.task_param.test_config.test_num"
          placeholder="请输入"
        />
      </el-form-item>
    </el-row>
    <el-divider />
    <div class="title">
      <svg-icon name="icon-save" />
      <h3>保存配置</h3>
    </div>
    <el-form-item label="训练样本数据" prop="task_param.save_config.training_sample_data.save_enable">
      <el-space>
        开启存储
        <el-switch
          :disabled="formData.task_param.task_config.mode == 'Inference'"
          v-model="formData.task_param.save_config.training_sample_data.save_enable"
        />
      </el-space>
    </el-form-item>
    <el-form-item label="决策模型" prop="task_param.save_config.decision_model.save_enable">
      <el-space>
        开启存储
        <el-switch
          :disabled="formData.task_param.task_config.mode == 'Inference'"
          v-model="formData.task_param.save_config.decision_model.save_enable"
        />
      </el-space>
    </el-form-item>
    <div class="form-footer">
      <el-button type="primary" @click="handleCreateOrUpdate(false)" :loading="loading">保 存</el-button>
      <el-button type="primary" @click="handleCreateOrUpdate(true)" :loading="loading">保存并转下一步</el-button>
    </div>
  </el-form>
</template>
<style lang="scss" scoped>
.form-footer {
  display: flex;
  justify-content: center;
  padding-bottom: 20px;
}
.taskedit-form {
  margin: 0 auto;
  margin-top: 0;
  .title {
    display: flex;
    flex-direction: row;
    align-items: center;
    line-height: 42px;
    .svg-icon {
      width: 2em;
      height: 2em;
    }
    h3 {
      margin-left: 10px;
    }
  }
}

@media screen and (max-width: 640px) {
  .taskedit-form {
    width: 100%;
  }
}
@media screen and (min-width: 660px) {
  .taskedit-form {
    width: 80%;
  }
}
@media screen and (min-width: 1200px) {
  .taskedit-form {
    width: 60%;
  }
}
</style>
